package jp.gr.java_conf.genzo.wifinotify;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import jp.gr.java_conf.genzo.wifinotify.data.LogData;
import jp.gr.java_conf.genzo.wifinotify.data.LogTracker;
import jp.gr.java_conf.genzo.wifinotify.util.LocationUtil;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.Toast;

import com.google.ads.AdRequest;
import com.google.ads.AdView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

/**
 * ログ位置Activity
 */
public class LogMapActivity extends MapActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_view);
        // Look up the AdView as a resource and load a request.
        AdView adView = (AdView) this.findViewById(R.id.adView);
        adView.loadAd(new AdRequest());

        String apiKey = isDebugable() ? "0kv-anIRq_o6niL7jEGbdH616SVFmClwatvaHdQ"
                : "0kv-anIRq_o5WFY-tUfbeBj5Gy7KwMC4T_2fk_A";
        final MapView mapView = new MapView(this, apiKey);
        ((ViewGroup) findViewById(R.id.log_map)).addView(mapView);
        mapView.setClickable(true);
        mapView.setBuiltInZoomControls(true);

        // オーバーレイアイコンの指定
        List<Overlay> mapOverlays = mapView.getOverlays();
        MapItemizedOverlay[] overlays = new MapItemizedOverlay[] {
                new MapItemizedOverlay(getResources().getDrawable(
                        R.drawable.stat_sys_wifi_signal_0)),
                        new MapItemizedOverlay(getResources().getDrawable(
                                R.drawable.stat_sys_wifi_signal_2_fully)),
                                new MapItemizedOverlay(getResources().getDrawable(
                                        R.drawable.stat_sys_wifi_signal_3_fully)),
                                        new MapItemizedOverlay(getResources().getDrawable(
                                                R.drawable.stat_sys_wifi_signal_4_fully)),
        };

        LogTracker tracker = new LogTracker();
        Cursor c = tracker.getMapList();
        GeoPoint centerPos = null;
        boolean eof = c.moveToFirst();

        while (eof) {
            String ssid = c.getString(0);
            GeoPoint pos = new GeoPoint((int) (c.getDouble(1) * 1E6),
                    (int) (c.getDouble(2) * 1E6));

            if (centerPos == null)
                centerPos = pos;

            int level = WifiManager.calculateSignalLevel(c.getInt(3), 4);

            OverlayItem item = new OverlayItem(pos, ssid, String.valueOf(c
                    .getInt(3)));
            overlays[level].addOverlay(item);
            eof = c.moveToNext();
        }
        c.close();
        tracker.close();

        for (MapItemizedOverlay ovl : overlays) {
            if (ovl.size() > 0) {
                mapOverlays.add(ovl);
            }
        }

        LogData logData = (LogData) getIntent().getSerializableExtra("data");
        if (logData != null) {
            centerPos = new GeoPoint((int) (logData.getLat() * 1E6),
                    (int) (logData.getLon() * 1E6));
        } else {
            final LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            LocationListener listener = new LocationListener() {
                @Override
                public void onLocationChanged(Location loc) {

                    GeoPoint centerPos = new GeoPoint(
                            (int) (loc.getLatitude() * 1E6),
                            (int) (loc.getLongitude() * 1E6));
                    MapController controller = mapView.getController();
                    controller.setCenter(centerPos);

                    lm.removeUpdates(this);
                }

                @Override
                public void onProviderDisabled(String provider) {
                }

                @Override
                public void onProviderEnabled(String provider) {
                }

                @Override
                public void onStatusChanged(String provider, int status,
                        Bundle extras) {
                }
            };

            LocationUtil.getLoaction(listener);

        }

        // 中心位置の指定
        MapController controller = mapView.getController();
        if (centerPos != null) {
            controller.setCenter(centerPos);
        }

        // 倍率の設定
        controller.setZoom(16);

    }

    // 必須
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    public boolean isDebugable() {
        PackageManager manager = getPackageManager();
        ApplicationInfo appInfo = null;
        try {
            appInfo = manager.getApplicationInfo(getPackageName(), 0);
        } catch (NameNotFoundException e) {
            return false;
        }
        if ((appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == ApplicationInfo.FLAG_DEBUGGABLE)
            return true;
        return false;
    }

    class MapItemizedOverlay extends ItemizedOverlay<OverlayItem> {

        ArrayList<OverlayItem> overlays = new ArrayList<OverlayItem>();
        Drawable mDrawable = null;

        public MapItemizedOverlay(Drawable drawable) {
            super(boundCenterBottom(drawable));
            mDrawable = drawable;
        }

        public void addOverlay(OverlayItem overlay) {
            overlays.add(overlay);
            populate();
        }

        @Override
        protected OverlayItem createItem(int i) {
            return overlays.get(i);
        }

        @Override
        public int size() {
            return overlays.size();
        }

        private Toast mToast = null;
        private final DecimalFormat DCF = new DecimalFormat("###.#####");

        @Override
        protected boolean onTap(int index) {
            OverlayItem item = overlays.get(index);

            String text = String.format("%s(%s)\n[%s,%s]", item.getTitle(),
                    item.getSnippet(),
                    DCF.format(item.getPoint().getLatitudeE6() / 1E6),
                    DCF.format(item.getPoint().getLongitudeE6() / 1E6));
            if (mToast != null) {
                mToast.cancel();
            }
            mToast = Toast.makeText(LogMapActivity.this, text,
                    Toast.LENGTH_SHORT);
            mToast.show();

            // findViewById(R.id.point_detail).setVisibility(View.VISIBLE);
            // TextView target = null;
            // target = (TextView) findViewById(R.id.log_ssid);
            // target.setText(item.getTitle());
            //
            // target = (TextView) findViewById(R.id.log_rssi);
            // target.setText("rssi=" + item.getSnippet());
            //
            // ImageView iv = (ImageView) findViewById(R.id.log_level_icon);
            // iv.setBackgroundDrawable(mDrawable);
            //
            // target = (TextView)findViewById(R.id.log_lat_lon);
            // target.setText(DCF.format(item.getPoint().getLatitudeE6()/1E6) +
            // "," + DCF.format(item.getPoint().getLongitudeE6()/1E6));
            //
            // findViewById(android.R.id.content).requestLayout();

            // return super.onTap(index);
            return true;
        }
    }

    class GeoPointBag {
        protected double mLat = 0.0d;
        protected double mLon = 0.0d;
        protected String mTitle;
        protected String mSnippet;

        public boolean isNear(double lat, double lon) {
            boolean result = false;
            if (mLat == 0.0d && mLon == 0.0d) {
                return true;
            }

            float[] distance = new float[3];
            Location.distanceBetween(mLon, lon, mLat, lat, distance);

            if (distance[0] < 10.0d) {
                // 近いと判定
                mLon = (mLon + lon) / 2;
                mLat = (mLat + lat) / 2;
                result = true;
            }

            return result;
        }

    }
}
